package com.ds.infrastructure.hyperspace.container.flow.operation;

import com.ds.infrastructure.hyperspace.common.flow.DuplexFlowContext;
import com.ds.infrastructure.hyperspace.container.endpoint.connector.NettyEndpointNodeStream;
import com.ds.infrastructure.hyperspace.container.endpoint.destination.TargetEndpointNode;
import com.ds.infrastructure.hyperspace.container.endpoint.destination.TargetProtocolAdapter;

/**
 * @author  Weishaoying
 */
public interface TargetFlowOperation<C extends DuplexFlowContext> extends FlowOperation<C> {

    /**
     * Handle target input data
     * @param duplexFlowContext
     * @param data
     */
    void handleInput(C duplexFlowContext, Object data);

    /**
     * No more things for this request
     * @param duplexFlowContext
     */
    void handleInputComplete(C duplexFlowContext);

    /**
     * Notified by target channel active
     * @param targetEndpointNode
     * @param stream
     * @param targetProtocolAdapter
     */
    void handleChannelActive(TargetEndpointNode targetEndpointNode, NettyEndpointNodeStream stream,
            TargetProtocolAdapter targetProtocolAdapter);

    /**
     * Notified by target channel inactive
     * @param targetProtocolAdapter
     * @param targetEndpointNode
     * @param stream
     * @param duplexFlowContext
     */
    void handleChannelInactive(TargetEndpointNode targetEndpointNode, NettyEndpointNodeStream stream,
            TargetProtocolAdapter targetProtocolAdapter, C duplexFlowContext);

    /**
     * Notified by occur exception
     * @param targetEndpointName
     * @param cause
     */
    void handleExceptionCaught(String targetEndpointName, Throwable cause);

    /**
     * Notified while request pending increment
     * @param targetEndpointName
     * @param zone
     */
    void handlePendingRequestIncrement(String targetEndpointName, String zone);

    /**
     * Notified while request pending decrement
     * @param targetEndpointName
     * @param zone
     */
    void handlePendingRequestDecrement(String targetEndpointName, String zone);

    /**
     * Notified while node status changed
     * @param targetEndpointName
     * @param nodeInfo
     * @param status
     */
    void handleTargetNodeStatusChange(String targetEndpointName, String nodeInfo, int status);

}
